using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Web;
using System.Net;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.Security;

namespace Georedirector
{
    [Microsoft.SharePoint.Security.SharePointPermission(System.Security.Permissions.SecurityAction.Assert,Unrestricted=true)]
    [Guid("0f31f5c6-302d-4f81-afaf-34af4195afe9")]
    public class GeoRedirectWebpart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private bool _error = false;
        private string defaultCountryCode = null;
        private string defaultGeoUrl = null;
        private string redirectRootUrl = null;
        


        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("GeoRedirect")]
        [WebDisplayName("Default Country code")]
        [WebDescription("If no language web is found, this country code is used")]
        public string DefaultCountryCode
        {
            get
            {
                if (defaultCountryCode == null)
                {
                    defaultCountryCode = "";
                }
                return defaultCountryCode;
            }
            set { defaultCountryCode = value; }
        }

        

        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("GeoRedirect")]
        [WebDisplayName("Redirect root url")]
        [WebDescription("Url of the root where the redirection starts")]
        public string RedirectRootUrl
        {
            get
            {
                if (redirectRootUrl == null)
                {
                    redirectRootUrl = "./";
                }
                return redirectRootUrl;
            }
            set { redirectRootUrl = value; }
        }

        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("GeoRedirect")]
        [WebDisplayName("GeoLocation Url")]
        [WebDescription("Url of the geolocation service")]
        public string GeoLocationUrl
        {
            get
            {
                if (defaultGeoUrl == null)
                {
                    defaultGeoUrl = "http://api.hostip.info/country.php?ip={0}";
                }
                return defaultGeoUrl;
            }
            set { defaultGeoUrl = value; }
        }



        public GeoRedirectWebpart()
        {
            this.ExportMode = WebPartExportMode.All;
        }



        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {

                    base.CreateChildControls();
                    string redirect = string.Empty;
                    string checkUrl = RedirectRootUrl;
                    if (!checkUrl.EndsWith("/"))
                    {
                        checkUrl += "/";
                    }

                    //No redirects for site admin's, so page can be edited
                    if (!SPContext.Current.Web.CurrentUser.IsSiteAdmin)
                    {
                        string myIp = HttpContext.Current.Request.UserHostAddress;
                        //test 81.207.138.93 => nl
                        //test 67.159.20.108 => US
                        string countryCode;
                        using (WebClient webClient = new WebClient())
                        {
                            countryCode = webClient.DownloadString(String.Format(GeoLocationUrl, myIp));
                        }
                        
                        if (countryCode == "XX")//Not found
                        {
                            redirect = checkUrl + DefaultCountryCode;
                        }
                        else
                        {

                            redirect = checkUrl + countryCode;
                            //Make a http request to check is the page exist
                            //http request , so the RedirectRootUrl doesn't have to be a SharePoint site
                            HttpWebRequest checkRequest = (HttpWebRequest)WebRequest.Create(redirect);
                            checkRequest.Credentials = CredentialCache.DefaultCredentials;
                            try
                            {
                                HttpWebResponse httpWebResponse = (HttpWebResponse)checkRequest.GetResponse();
                            }
                            catch(WebException webEx)
                            {
                                // 404 throws exception redirect to default
                                redirect = checkUrl + defaultCountryCode;
                            }
                        }

                        Page.Response.Redirect(redirect, false);

                    }

                    //Fallback for search engines etc
                    redirect = checkUrl + DefaultCountryCode + "/";
                    Literal fallBackLink = new Literal();
                    fallBackLink.ID = "fallBackLink";
                    fallBackLink.Text = String.Format("You should be automatically redirected to <a href=\"{0}\">{0}</a> ", redirect);

                    Controls.Add(fallBackLink);
                    
                    


                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            if (!_error)
            {
                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    // Your code here...
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }
    }
}

